ES6 ES2015
块级声明
新增了 let
和 const
,基本告别了 var 带来的变量提升问题
let
- 声明一个变量,且仅在当前{}
块级作用域内可用,可被重新赋值const
- 声明一个常量,且仅在当前{}
块级作用域内可用,不可被重新赋值
主要区别:
const
声明后需要马上赋值,let声明后可以在使用的时候再赋值const
和 let 都不存在变量提升问题,也称为暂时性死区,是一个新概念
特性 | var | let | const |
---|---|---|---|
变量提升 | ✔️ | ⛔ | ⛔ |
全局变量 | ✔️ | ⛔ | ⛔ |
重复声明 | ✔️ | ⛔ | ⛔ |
重新赋值 | ✔️ | ✔️ | ⛔ |
暂时性死区 | ⛔ | ✔️ | ✔️ |
块作用域 | ⛔ | ✔️ | ✔️ |
只声明不初始化 | ✔️ | ✔️ | ⛔ |
let
和const
是可以完全替代var
,而且也请务必替代var
!
基本类型
Symbol
复杂类型
map
set
字符串
模板字符串
const name = 'capsion';
const str = `Your name is ${name}`;
对象
简洁表示法
class Person {
age = 18
}
// 完全等价于
const Person = {
age:18
}
Object.is()
判断两个值是否相等
语法
Object.is(value1:any, value2:any) : booleen
与
"=="
运算不同,不会触发两边值的强制转换,类似===
与
"==="
区别+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
Object.assgin()
对象的浅复制,浅合并,返回原对象
类
class Person {
constructor(name) {
this.name = 'capsion';
}
console() {
console.log(this.name);
}
}
模块化
数组
扩展运算符
// 复制数组
const arr = [...arr1]
// 合并数组
const arr = [...arr1, ...arr2]
// 拼接数组
arr.push(...arr1)
// 类似apply
Math.max(...[x, y])
// 转换字符串为数组
const arr = [..."hello"]
// 类数组对象转换为数组
const arr = [...Arguments, ...NodeList]
// 可遍历对象转换为数组
const arr = [...String, ...Set, ...Map, ...Generator]
// 与数组解构赋值结合
const [x, ...rest/spread] = [1, 2, 3]
// 计算Unicode字符长度
const len = [..."hello"].length
// 将字符串解构
let a = [...'hello world']; // ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]
Array.from()
Array.of()
Promise
Promise.resolve().then(() => { console.log(2); });
console.log(1);
// 先打印 1 ,再打印 2
函数
箭头函数
const func = (a, b) => a + b;
func(1, 2); // 3
函数参数默认值
function foo(age = 25,){
// ...
}
解构赋值
解构这个特性是ES6是一个非常非常使用的特性,是必须掌握甚至滚瓜烂熟的,因为其对整体编写代码和可读性都有很大的提高,而且用处非常多。
具有 Iterator 接口的数据结构,都可以采用数组形式的解构赋值。
字符串解构
const [frist, second, ...rest] = "capsion";
console.log("frist: ", [frist, second, rest]); //frist: [ 'c', 'a', [ 'p', 's', 'i', 'o', 'n' ] ]
数组解构
当一个对象具有 Iterator 特性是,就可以采用数组形式的解构
const [frist, second, ...rest] = [1, 2, 3, 4, 5, 6];
console.log("frist: ", [frist, second, rest]); // frist: [ 1, 2, [ 3, 4, 5, 6 ] ]
对象解构
const { x, y } = { x: 1, y: 2, z: 3 };
console.log("{ x, y }: ", { x, y }); // 1 2
// 设置默认值
const { x, y, Z = 5 } = { x: 1, y: 2, z: 3 };
// 更改复制参数名
const { x, y, z:coord_z = 5 } = { x: 1, y: 2, z: 3 };
console.log(x, y, coord_z); // 1 2 3
函数参数解构
// 数组参数
function Func([x = 0, y = 1]) {}
// 对象参数
function Func({ x = 0, y = 1 } = {}) {}
实用场景
两个变量交换
let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x, y); // 2 1返回值解构
// 返回的结构解构
const {x,y} = getCoords() => {x:int, y:int}
const [x,y,z] = getCoords() => Array局部提取 json 对象
const {name, version} = packageJson
遍历中使用
// 遍历对象
for (let [key,value] of Map){ ../ }导入模块时结构
const { log } = require('console')
// 或
import { log } from 'console'
独立的进制表示方式
ES6 提供了二进制和八进制数值的最新的写法,分别用前缀 0b(0B)
和 0o(0O)
表示。
// 503 的二进制和八进制表示:
0b111110111 === 503 // true
0o767 === 503 // true
ES5 开始,在严格模式中,八进制就不再允许使用前缀 0 表示,ES6 进一步明确要使用前缀 0o 表示。
// 非严格模式
(function(){
console.log(0o11 === 011);
})() // true
// 严格模式
'use strict';
(function(){
console.log(0o11 === 011);
})() // Uncaught SyntaxError: Octal literals are not allowed in strict mode.
应用场景:
- 十进制转换
// 如果要将 0b 和 0o 前缀的字符串数值转换为十进制,要使用 Number 方法。
Number('0b111') // 7
Number('0o10') // 8
小数精度处理
JavaScript 在处理浮点数时,很容易会遇到结算精度问题,这跟JS采用IEEE 754
标准计算浮点数有关,特别是一些财务记账场合,需要计算小数时使用js很容易出现天坑
而Number.EPSILON
实际上是 JavaScript 能够表示的最小精度。误差如果小于这个值,就可以认为已经没有意义了,即不存在误差了。引入一个这么小的量的目的,在于为浮点数计算,设置一个误差范围。我们知道浮点数计算是不精确的。因此,Number.EPSILON的实质是一个可以接受的最小误差范围。
不使用Number.EPSILON
时,一般通过以下两种方法
方法1:使用
toFixed()
parseFloat((0.1+0.2).toFixed(10)) === 0.3 // true
方法2:把计算数字 提升 10 的N次方 倍 再 除以10的N次方。一般都用 1000 就行
(0.1*1000+0.2*1000)/1000==0.3 // true
const math = require('math')
使用 Number.EPSILON
:
// 这里做一个 Number.EPSILON 是否存在,存在最好,不存在则重新定义
if (!Number.EPSILON) {
Number.EPSILON = Math.pow(2,-52)
}
// 判断实际值和计算值是否相等(即是否在误差范围内)
function show(n1,n2){
return Math.abs(n1-n2)<Number.EPSILON
}
console.log(show(0.1+0.2,0.3)) // true
应用场合
小数计算
(0.1 + 0.2) == 0.3 // false